package com.huey.utils.classType;

import com.google.common.collect.Lists;

import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author xubo
 * @date 2022/3/30 15:51
 */
public class ClassTypeUtil {
    public final static String INTEGER1 = "java.lang.Integer";

    public final static String BYTE1 = "java.lang.Byte";

    public final static String LONG1 = "java.lang.Long";

    public final static String DOUBLE1 = "java.lang.Double";

    public final static String FLOAT1 = "java.lang.Float";

    public final static String CHARACTER1 = "java.lang.Character";

    public final static String SHORT1 = "java.lang.Short";

    public final static String BOOLEAN1 = "java.lang.Boolean";

    public final static String STRING1 = "java.lang.String";

    public final static String BIGDECIMAL1 = "java.math.BigDecimal";





    public static Object getFieldValue(Object object, Field field) {
        Object value;
        try {
            value = field.get(object);
        } catch (IllegalAccessException e) {
            return null;
        }
        switch (field.getType().getName()) {
            case INTEGER1:
            case LONG1:
            case SHORT1:
                return Objects.isNull(value) ? 0 : value;
            case FLOAT1:
            case DOUBLE1:
                return Objects.isNull(value) ? 0 : new BigDecimal(String.valueOf(value)).setScale(2, BigDecimal.ROUND_HALF_UP);
            case BIGDECIMAL1:
                return Objects.isNull(value) ? 0 : ((BigDecimal) value).setScale(2, BigDecimal.ROUND_HALF_UP);
            default:
                return value;
        }
    }
    public static <T> String getColumnName(Object fn) {
        // 从function取出序列化方法
        Method writeReplaceMethod;
        try {
            writeReplaceMethod = fn.getClass().getDeclaredMethod("writeReplace");
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        }

        // 从序列化方法取出序列化的lambda信息
        boolean isAccessible = writeReplaceMethod.isAccessible();
        writeReplaceMethod.setAccessible(true);
        SerializedLambda serializedLambda;
        try {
            serializedLambda = (SerializedLambda) writeReplaceMethod.invoke(fn);
        } catch (IllegalAccessException | InvocationTargetException e) {
            throw new RuntimeException(e);
        }
        writeReplaceMethod.setAccessible(isAccessible);

        // 从lambda信息取出method、field、class等
        String fieldName = serializedLambda.getImplMethodName().substring("get".length());
        fieldName = fieldName.replaceFirst(fieldName.charAt(0) + "", (fieldName.charAt(0) + "").toLowerCase());
        return fieldName;

    }


    private <T> void initParams(List<?> fixedConfigVOs, T result) {
        //Map<String, String> collect = fixedConfigVOs.stream().collect(Collectors.toMap(FixedConfigVO::getFieldKey, FixedConfigVO::getFieldValue, (k1, k2) -> k1));
        Field[] declaredFields = result.getClass().getDeclaredFields();
        for(Field field:declaredFields){
            String value =null; //collect.get(field.getName());
            String name = field.getName().replaceFirst(field.getName().substring(0, 1), field.getName().substring(0, 1).toUpperCase());
            Method method =null;
            try {
                method = result.getClass().getMethod("set" + name,field.getType());
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
            method.setAccessible(true);
            try {
                method.invoke(result, value);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    }






    public <T> void convertData(Field[] fields, List<?> scFixedConfigPOS,
                                Integer docType,String bookId,T t){
        for(Field field:fields){
            String name = field.getName().replaceFirst(field.getName().substring(0, 1), field.getName().substring(0, 1).toUpperCase());
            Method method =null;
            try {
                method = t.getClass().getMethod("get" + name);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
            method.setAccessible(true);
            Object value=null;
            try {
                value=method.invoke(t);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    }
}
